/* Copyright (c) [2025] [zhi1208@126.com]
 * SPDX-License-Identifier: MIT
 */

/*********************
 *      INCLUDES
 *********************/
#include "lvgl.h"
#include "hmi_pg_def.h"
#include "hmi_config.h"
#include "hmi_anim.h"
#include "hmi_list_item.h"
#include "hmi_tinyttf.h"
#include "hmi_top_bar.h"
#include "hmi_subjects.h"
#include "hmi_bg.h"
#include "hmi_pg_navigation.h"
#include "hmi_hal.h"
#include "hmi_pages.h"
#include "hmi_loading_toast.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void create();
static void del();
static void enter_anim(lv_anim_completed_cb_t cb, uint32_t delay);
static uint32_t exit_anim(lv_anim_completed_cb_t cb, hmi_pg_t *enter_pg);

static void connected_wifi_observer_cb(lv_observer_t *observer, lv_subject_t *subject);

static void wifi_list_item_create(char *ssid);
static void wifi_list_clean();
static void wifi_list_update_timer_cb(lv_timer_t *t);
static void wifi_list_item_click_cb(lv_event_t *e);

/**********************
 *  STATIC VARIABLES
 **********************/
static hmi_pg_t wifi = {
    .name = "WiFi",
    .del_on_pop = 1,
    .bg_color = 0x7dace4,
    .create = create,
    .del = del,
    .enter_anim = enter_anim,
    .exit_anim = exit_anim,
};

static lv_obj_t *avail_wifi;

static lv_timer_t *wifi_list_update_timer;

static lv_font_t *def_font_16;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
hmi_pg_t *hmi_pg_wifi()
{
    return &wifi;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void create()
{
    wifi.bg_y = HMI_BG_NORMAL;

    wifi.root = lv_obj_create(NULL);
    lv_obj_remove_style_all(wifi.root);
    lv_obj_set_style_pad_bottom(wifi.root, 10, 0);
    lv_obj_set_flex_flow(wifi.root, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_flex_align(wifi.root, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
    lv_obj_remove_flag(wifi.root, LV_OBJ_FLAG_SCROLLABLE);

    hmi_top_bar_create(wifi.root, wifi.name);

    lv_obj_t *cont = lv_obj_create(wifi.root);
    lv_obj_set_width(cont, lv_pct(94));
    lv_obj_set_style_pad_row(cont, 20, 0);
    lv_obj_set_style_border_width(cont, 0, 0);
    lv_obj_set_flex_grow(cont, 1);
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);

    if (!def_font_16)
        def_font_16 = hmi_tiny_ttf_create_static("def_font", 16, 0);

    lv_obj_t *conn_wifi = lv_obj_create(cont);
    lv_obj_remove_style_all(conn_wifi);
    lv_obj_set_size(conn_wifi, lv_pct(100), LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(conn_wifi, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_flex_align(conn_wifi, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_subject_add_observer_obj(&hmi_wifi_subj, connected_wifi_observer_cb, conn_wifi, NULL);

    avail_wifi = lv_obj_create(cont);
    lv_obj_remove_style_all(avail_wifi);
    lv_obj_set_flex_grow(avail_wifi, 1);
    lv_obj_set_width(avail_wifi, lv_pct(100));
    lv_obj_set_flex_flow(avail_wifi, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_flex_align(avail_wifi, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);

#ifndef LV_PORT_VS_CODE
    hmi_loading_toast_open();
#endif

    wifi_list_update_timer = lv_timer_create(wifi_list_update_timer_cb, 10000, NULL);
    lv_timer_set_repeat_count(wifi_list_update_timer, -1);
    lv_timer_ready(wifi_list_update_timer);

#ifdef LV_PORT_VS_CODE
    wifi_list_item_create("test ap1");
    wifi_list_item_create("test ap2");
    wifi_list_item_create("test ap3");
    wifi_list_item_create("test ap4");
    wifi_list_item_create("test ap5");
    wifi_list_item_create("test ap6");
    wifi_list_item_create("test ap7");
    wifi_list_item_create("test ap8");
    wifi_list_item_create("test ap9");
#endif
}

static void del()
{
    lv_timer_delete(wifi_list_update_timer);
    wifi_list_update_timer = NULL;

    lv_obj_delete_async(wifi.root);
    wifi.root = NULL;
    avail_wifi = NULL;

    if (def_font_16)
    {
        hmi_tiny_ttf_del(def_font_16);
        def_font_16 = NULL;
    }
}

static void enter_anim(lv_anim_completed_cb_t cb, uint32_t delay)
{
    hmi_enter_anim_default(wifi.root, cb, delay);
}

static uint32_t exit_anim(lv_anim_completed_cb_t cb, hmi_pg_t *enter_pg)
{
    return hmi_exit_anim_default(wifi.root, cb, enter_pg);
}

static void connected_wifi_observer_cb(lv_observer_t *observer, lv_subject_t *subject)
{
    int32_t wifi_is_connected = lv_subject_get_int(subject);
    lv_obj_t *obj = lv_observer_get_target_obj(observer);

    if (wifi_is_connected)
    {
        char *ssid = hmi_hal_connected_wifi_get();

        if (ssid)
        {
            lv_obj_clean(obj);

            lv_obj_t *conn_wifi_title = lv_label_create(obj);
            lv_obj_set_style_text_font(conn_wifi_title, def_font_16, 0);
            lv_label_set_text(conn_wifi_title, "当前已连接WiFi");

            hmi_list_item_cfg_t cfg = {.title = ssid};
            lv_obj_t *conn_wifi_list = hmi_list_item_create(obj, &cfg);
            lv_obj_set_style_recolor_opa(conn_wifi_list, LV_OPA_COVER, 0);
            lv_obj_set_style_recolor(conn_wifi_list, lv_color_hex(wifi.bg_color), 0);

            lv_obj_remove_flag(obj, LV_OBJ_FLAG_HIDDEN);
        }
    }
    else
    {
        lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
    }
}

static void wifi_list_item_create(char *ssid)
{
    if (!avail_wifi)
        return;

    hmi_list_item_cfg_t cfg = {.title = ssid, .click_cb = wifi_list_item_click_cb};
    hmi_list_item_create(avail_wifi, &cfg);
}

static void wifi_list_clean()
{
    if (avail_wifi)
        lv_obj_clean(avail_wifi);
}

static void wifi_list_update_timer_cb(lv_timer_t *t)
{
    LV_UNUSED(t);

    if (hmi_get_cur_page() == &wifi)
    {
        hmi_hal_wifi_list_ops_t *ops = lv_malloc(sizeof(hmi_hal_wifi_list_ops_t));
        ops->clean = wifi_list_clean;
        ops->item_creat = wifi_list_item_create;
        ops->loading_anim_start = hmi_loading_toast_open;
        ops->loading_anim_stop = hmi_loading_toast_close;

        hmi_hal_avail_wifi_list_get(ops);
    }
}

static void wifi_list_item_click_cb(lv_event_t *e)
{
    lv_obj_t *item = lv_event_get_current_target(e);

    hmi_pg_wifi_pwd()->name = hmi_list_item_get_title(item);
    hmi_pg_push(hmi_pg_wifi_pwd());
}